/*-------------------------------------------------------------------------
 *
 * gistdesc.c
 *	  rmgr 描述例程，用于 access/gist/gistxlog.c
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/access/rmgrdesc/gistdesc.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/gistxlog.h"
#include "lib/stringinfo.h"
#include "storage/relfilenode.h"

static void fc_out_gistxlogPageUpdate(StringInfo fc_buf, gistxlogPageUpdate *fc_xlrec)
{
}

static void fc_out_gistxlogPageReuse(StringInfo fc_buf, gistxlogPageReuse *fc_xlrec)
{
	appendStringInfo(fc_buf, "rel %u/%u/%u; blk %u; latestRemovedXid %u:%u",
					 fc_xlrec->node.spcNode, fc_xlrec->node.dbNode,
					 fc_xlrec->node.relNode, fc_xlrec->block,
					 EpochFromFullTransactionId(fc_xlrec->latestRemovedFullXid),
					 XidFromFullTransactionId(fc_xlrec->latestRemovedFullXid));
}

static void fc_out_gistxlogDelete(StringInfo fc_buf, gistxlogDelete *fc_xlrec)
{
	appendStringInfo(fc_buf, "delete: latestRemovedXid %u, nitems: %u",
					 fc_xlrec->latestRemovedXid, fc_xlrec->ntodelete);
}

static void fc_out_gistxlogPageSplit(StringInfo fc_buf, gistxlogPageSplit *fc_xlrec)
{
	appendStringInfo(fc_buf, "page_split: splits to %d pages",
					 fc_xlrec->npage);
}

static void fc_out_gistxlogPageDelete(StringInfo fc_buf, gistxlogPageDelete *fc_xlrec)
{
	appendStringInfo(fc_buf, "deleteXid %u:%u; downlink %u",
					 EpochFromFullTransactionId(fc_xlrec->deleteXid),
					 XidFromFullTransactionId(fc_xlrec->deleteXid),
					 fc_xlrec->downlinkOffset);
}

void gist_desc(StringInfo fc_buf, XLogReaderState *fc_record)
{
	char	   *fc_rec = XLogRecGetData(fc_record);
	uint8		fc_info = XLogRecGetInfo(fc_record) & ~XLR_INFO_MASK;

	switch (fc_info)
	{
		case XLOG_GIST_PAGE_UPDATE:
			fc_out_gistxlogPageUpdate(fc_buf, (gistxlogPageUpdate *) fc_rec);
			break;
		case XLOG_GIST_PAGE_REUSE:
			fc_out_gistxlogPageReuse(fc_buf, (gistxlogPageReuse *) fc_rec);
			break;
		case XLOG_GIST_DELETE:
			fc_out_gistxlogDelete(fc_buf, (gistxlogDelete *) fc_rec);
			break;
		case XLOG_GIST_PAGE_SPLIT:
			fc_out_gistxlogPageSplit(fc_buf, (gistxlogPageSplit *) fc_rec);
			break;
		case XLOG_GIST_PAGE_DELETE:
			fc_out_gistxlogPageDelete(fc_buf, (gistxlogPageDelete *) fc_rec);
			break;
		case XLOG_GIST_ASSIGN_LSN:
			/* 没有细节要写 */
			break;
	}
}

const char * gist_identify(uint8 fc_info)
{
	const char *fc_id = NULL;

	switch (fc_info & ~XLR_INFO_MASK)
	{
		case XLOG_GIST_PAGE_UPDATE:
			fc_id = "PAGE_UPDATE";
			break;
		case XLOG_GIST_DELETE:
			fc_id = "DELETE";
			break;
		case XLOG_GIST_PAGE_REUSE:
			fc_id = "PAGE_REUSE";
			break;
		case XLOG_GIST_PAGE_SPLIT:
			fc_id = "PAGE_SPLIT";
			break;
		case XLOG_GIST_PAGE_DELETE:
			fc_id = "PAGE_DELETE";
			break;
		case XLOG_GIST_ASSIGN_LSN:
			fc_id = "ASSIGN_LSN";
			break;
	}

	return fc_id;
}
